import draw.*;
import geometry.*;
import tester.*;
import tester.cobertura.Instrument;

import java.util.*;

import colors.*;

/**
 * @uml.dependency   supplier="ITileList"
 * @uml.dependency   supplier="Player"
 */

@Instrument
class GameWorld extends World{
	
  /**
 * @uml.property  name="width"
 */
int width = 1024;
  /**
 * @uml.property  name="height"
 */
int height = 600;
  /**
 * @uml.property  name="lot"
 * @uml.associationEnd  multiplicity="(1 1)"
 */
ITileList lot;
  /**
 * @uml.property  name="p"
 * @uml.associationEnd  multiplicity="(1 1)"
 */
Player p;
  /**
 * @uml.property  name="time"
 */
int time;
  /**
 * @uml.property  name="tileheight"
 */
int tileheight = 20;
  /**
 * @uml.property  name="r"
 */
Random r = new Random();
  
  GameWorld(ITileList lot, Player p, int time){
    this.lot = lot;
    this.p = p;
    this.time = time;
  }
  
  //updates the world according to the tick.
  public World onTick(){
	  this.time++;
	 if(time == 35){
		 this.time = 0;
		 return new GameWorld (addRow(15, lot), p, this.time);
	 }
	  if(this.lot.hitp(this.p))
	  		return endOfWorld("You Lose!");
	  else return new GameWorld(this.lot.onTick(), this.p.onTick(), this.time);
  }
  
  //Adds a row of randomized tiles.
  public ITileList addRow(int counter, ITileList alot){
		if(counter > 0){
			return new ConsLot(makeTile(), addRow(--counter, alot));
		} else {
			return alot;
		}
  }
 
  //makes a random tile.
  public Tile makeTile(){
	 return new Tile(new Posn(r.nextInt(1000),
			 -(this.tileheight / 2)), new Red());
  }
  
  // Calls the draw functions of the tiles and the player.
  public boolean draw(){
    return this.lot.draw(theCanvas) && this.p.draw(theCanvas);
  }
  
  //the key handler function.
  public World onKeyEvent(String ke){
	  return new GameWorld(lot, this.p.onKeyEvent(ke), this.time);
  }
  
  /*
  TEMPLATE:
     FIELDS:
      ... this.width ...          -- int
      ... this.height ...         -- int
      ... this.lot ...            -- ITileList
      ... this.p ...              -- Player
      ... this.time ...           -- int
      ... this.tileheight ...     -- int
      ... this.r ...              -- Random
   
      METHODS:
      ... this.onTick() ...       			            -- World
      ... this.draw(Canvas c) ...       				-- boolean
      ... this.addRow(int counter, ITileList lot) ...   -- ITileList
      ... this.makeTile() ...                           -- Tile
      ... this.onKeyEvent(String ke) ...                -- World

      METHODS FOR FIELDS:
      ... this.p.onTick() ...              -- Player
      ... this.p.draw(Canvas c) ...        -- boolean
      ... this.p.center() ...              -- Posn
      ... this.p.onKeyEvent(String ke) ... -- Player
      ... this.lot.onTick() ...             -- Tile
      ... this.lot.hitGroundp() ...         -- boolean
      ... this.lot.draw(Canvas c) ...       -- boolean
      ... this.lot.hitp(Player p) ...       -- boolean
      ... this.lot.distanceToX(Player p) ...-- double
      ... this.lot.distanceToY(Player p) ...-- double
      ... this.lot.center() ...             -- Posn

  */ 
}